package com.example.filter;

import com.example.config.EncryptionConfig;
import com.example.util.AesUtil;
import com.example.wrapper.CachedBodyHttpServletRequest;
import com.example.wrapper.DecryptedRequestWrapper;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

public class RequestDecryptFilter implements Filter {

    private static final Logger logger = LoggerFactory.getLogger(RequestDecryptFilter.class);

    private final EncryptionConfig encryptionConfig;
    private final ObjectMapper objectMapper;

    // 构造方法注入
    public RequestDecryptFilter(EncryptionConfig encryptionConfig, ObjectMapper objectMapper) {
        this.encryptionConfig = encryptionConfig;
        this.objectMapper = objectMapper;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;

        // 检查请求头是否指示请求体是加密的
        if ("true".equalsIgnoreCase(httpRequest.getHeader("X-Encrypted")) && encryptionConfig.isDecryptionEnabled()) {
            CachedBodyHttpServletRequest cachedRequest = new CachedBodyHttpServletRequest(httpRequest);

            // 读取缓存的请求体
            byte[] cachedRequestBody = cachedRequest.getContentAsByteArray();

            if (cachedRequestBody.length > 0) {
                // 假设加密的内容在JSON请求体的"encryptedData"字段中
                String requestBody = new String(cachedRequestBody, StandardCharsets.UTF_8);
                JsonNode jsonNode = objectMapper.readTree(requestBody);

                // 从请求体中提取加密的字符串
                String encryptedBody = jsonNode.get("encryptedData").asText();
                logger.info("收到的加密请求体: {}", encryptedBody);

                // 检查 Base64 字符串
                if (!AesUtil.isBase64(encryptedBody)) {
                    logger.error("收到的请求体不是有效的 Base64 编码字符串");
                    throw new ServletException("Invalid Base64 encoding");
                }

                String decryptedBody = AesUtil.decrypt(encryptionConfig.getKey(), encryptionConfig.getInitVector(), encryptedBody);
                if (decryptedBody == null) {
                    logger.error("解密失败，解密后的请求体为空");
                    throw new ServletException("Decryption failed");
                }
                logger.info("解密后的请求体: {}", decryptedBody);

                DecryptedRequestWrapper decryptedRequestWrapper = new DecryptedRequestWrapper(cachedRequest, decryptedBody);
                // 继续处理链
                chain.doFilter(decryptedRequestWrapper, response);
                return;
            }
        }

        // 如果没有加密，或者解密失败，则继续处理原始请求
        chain.doFilter(request, response);
    }
}
